/*
 * @ : Copyright (c) 2021 Phytium Information Technology, Inc. 
 *  
 * SPDX-License-Identifier: Apache-2.0.
 * 
 * @Date: 2021-09-01 15:44:29
 * @LastEditTime: 2021-09-01 18:59:13
 * @Description:  This files is for 
 * 
 * @Modify History: 
 *  Ver   Who        Date         Changes
 * ----- ------     --------    --------------------------------------
 */

#include <iostream>
#include <fstream>
#include "../elfio/elfio.hpp"
#include "elftool.h"

using namespace std;
using namespace ELFIO;

int ElfIoMerge(string &master_elf_path, vector<string> &slave_elf_paths,  string &output_elf_path)
{
    elfio master;
    ElfParseInfo elf_info;
    int ret;

    //Parse input elf, get ELF file info
    ret = ElfIoParse(master_elf_path, elf_info);

    //Read Master Elf, add a section to describe Slave Elf
    // Load ELF data
    if ( !master.load(master_elf_path) ) {
        cout << "Can't find or process Master ELF file " << master_elf_path << endl;
        return 2;
    }

    // Create additional section at the end of the file
    section* index_sec = master.sections.add( ".note.amp.slave.elf.index" );
    index_sec->set_type(SHT_NOTE);
    note_section_accessor index_writer( master, index_sec );
    index_writer.add_note( 0x01, "Slave 0", "Elf Address", 8 );

    master.save(output_elf_path);

    //Create MELF file for merging
    ofstream merge_out(output_elf_path, ios::out | ios::binary | ios::app);
    if (!merge_out.is_open())
    {
        cout << "Can't create merge ELF file" << output_elf_path << endl;
        return 2;
    }

    for (vector<string>::iterator it = slave_elf_paths.begin();
         it != slave_elf_paths.end(); it++)
    {
        ifstream slave_in(*it, ios::in | ios::binary);    

        if (!slave_in.is_open())
        {
            cout << "Can't read slave Elf file " << *it << endl;
            return 2;
        }
        else
        {
            //append slave elf at the end
            merge_out << slave_in.rdbuf();
        }
    }

    return ret;
}